home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGSCAL / PCOMPILE.LZH / BLOCK.PAS next >
Pascal/Delphi Source File  |  1985-03-05  |  43KB  |  1,451 lines

  1. { Facilis 0.20                                   file: BLOCK.PAS      }
  2.  
  3. overlay procedure blockov(fsys: symset; isfun: boolean; level: integer);
  4.  
  5. type   item = record
  6.                 typ: types; ref: index; temp: boolean
  7.               end;
  8.      conrec = record case tp: types of
  9.                        ints,chars,bools: (i:integer);
  10.                        reals: (r: real)
  11.                      end ;
  12.  
  13. var    dx : integer;    { data allocation index }
  14.        prt: integer;    { t-index of this procedure }
  15.        prb: integer;    { b-index of this procedure }
  16.        x  : integer;
  17.  
  18.   procedure skip(fsys: symset; n: integer);
  19.  
  20.   begin
  21.     error(n); skipflag := true;
  22.     while not (sy in fsys) do insymbol;
  23.     if skipflag then endskip
  24.   end  { skip } ;
  25.  
  26.   procedure test(s1,s2: symset; n: integer);
  27.  
  28.   begin
  29.     if not (sy in s1) then skip(s1+s2,n)
  30.   end  {test } ;
  31.  
  32.   procedure testsemicolon;
  33.  
  34.   begin
  35.     if sy = semicolon
  36.     then insymbol
  37.     else begin
  38.       error(14);
  39.       if sy in [comma,colon] then insymbol
  40.     end ;
  41.     test([ident]+blockbegsys, fsys, 6)
  42.   end  { testsemicolon } ;
  43.  
  44.   procedure enter(id: alfa; k:object);
  45.  
  46.   var    j,l: integer;
  47.   begin
  48.     if t = tmax
  49.     then fatal(1)
  50.     else begin
  51.       tab[0].name := id;
  52.       j := btab[display[level]].last;  l := j;
  53.       while tab[j].name <> id do  j := tab[j].link;
  54.       if j <> 0
  55.       then error(1)
  56.       else begin
  57.         t := t+1;
  58.         with tab[t] do
  59.         begin
  60.           name:= id;   link := l;
  61.           obj := k;     typ := notyp;   ref := 0;
  62.           lev := level; adr := 0
  63.         end ;
  64.         btab[display[level]].last := t
  65.       end
  66.     end
  67.   end  { enter } ;
  68.  
  69.   function loc(id: alfa): integer;
  70.  
  71.   var    i,j: integer;      { locate id in tabel }
  72.   begin
  73.     i := level; tab[0].name := id;    { sentinel }
  74.     repeat
  75.       j := btab[display[i]].last;
  76.       while tab[j].name <> id do  j := tab[j].link;
  77.       i := i-1;
  78.     until (i<0) or (j<>0);
  79.     if j = 0 then error(0);
  80.     loc := j
  81.   end  { loc } ;
  82.  
  83.   procedure entervariable;
  84.  
  85.   begin
  86.     if sy = ident
  87.     then begin
  88.       enter(id,vvariable); insymbol
  89.     end else error(2)
  90.   end  { entervariable } ;
  91.  
  92.   procedure constant(fsys: symset; var c: conrec);
  93.  
  94.   var    x, sign: integer;
  95.   begin
  96.     c.tp := notyp; c.i := 0;
  97.     test(constbegsys, fsys, 50);
  98.     if sy in constbegsys
  99.     then begin
  100.       if sy = charcon
  101.       then begin
  102.         c.tp := chars; c.i := inum;
  103.         insymbol
  104.       end else
  105.       if sy = stringcon
  106.       then begin
  107.         c.tp := strngs;
  108.         c.i := seg(spnt^);
  109.         insymbol
  110.       end else begin
  111.         sign := 0;
  112.         if sy in [plus,minus]
  113.         then begin
  114.           if sy = minus then sign := -1 else sign := 1;
  115.           insymbol
  116.         end ;
  117.         if sy = ident
  118.         then begin
  119.           x := loc(id);
  120.           if x <> 0
  121.           then if tab[x].obj <> konstant
  122.                then error(25)
  123.                else begin
  124.                  c.tp := tab[x].typ;
  125.                  if c.tp in [ints,reals] then
  126.                    if sign=0 then sign := 1;
  127.                  if c.tp = reals
  128.                  then c.r := sign*rconst[tab[x].adr]
  129.                  else if c.tp = ints
  130.                  then c.i := sign*tab[x].adr
  131.                  else begin
  132.                    if sign<>0 then error(33);
  133.                    c.i := tab[x].adr
  134.                  end
  135.                end ;
  136.           insymbol
  137.         end else begin
  138.           if sign=0 then sign := 1;
  139.           if sy = intcon
  140.             then begin
  141.               c.tp := ints; c.i := sign*inum;
  142.               insymbol
  143.             end else if sy = realcon
  144.                      then begin
  145.                        c.tp := reals; c.r := sign*rnum;
  146.                        insymbol
  147.                      end else skip(fsys,50)
  148.         end
  149.       end;
  150.       test(fsys,[], 6)
  151.     end
  152.   end  { constant } ;
  153.  
  154.   procedure typ(fsys: symset; var tp: types; var rf, sz: integer);
  155.  
  156.   var    eltp: types;
  157.          elrf,elsz,offset,x,t0,t1: integer;
  158.         dummy: conrec;
  159.  
  160.     procedure arraytyp(var aref,arsz: integer);
  161.  
  162.     var    eltp: types;
  163.            low, high: conrec;
  164.            elrf, elsz: integer;
  165.     begin
  166.       constant([twodots,rbrack,rparent,ofsy]+fsys, low);
  167.       if low.tp in [reals,strngs]
  168.       then  begin
  169.         error(27);
  170.         low.tp := ints; low.i := 0
  171.       end ;
  172.       if sy = twodots then insymbol else error(13);
  173.       constant([rbrack,comma,rparent,ofsy]+fsys, high);
  174.       if high.tp <> low.tp
  175.       then begin
  176.         error(27); high.i := low.i
  177.       end ;
  178.       enterarray(low.tp, low.i,high.i);
  179.       aref := a;
  180.       if sy = comma
  181.       then begin
  182.         insymbol;
  183.         eltp := arrays;
  184.         arraytyp(elrf,elsz)
  185.       end else begin
  186.         if sy = rbrack
  187.         then insymbol
  188.         else begin
  189.           error(12);
  190.           if sy = rparent then insymbol
  191.         end ;
  192.         if sy = ofsy then insymbol else error(8);
  193.         typ(fsys,eltp,elrf,elsz)
  194.       end ;
  195.  
  196.       with atab[aref] do
  197.       begin
  198.         arsz := (high-low+1)*elsz; size := arsz;
  199.         if arsz > stacksize then error(61);
  200.         eltyp := eltp; elref := elrf; elsize := elsz
  201.       end ;
  202.     end  {arraytyp } ;
  203.  
  204.   begin  { typ }
  205.     tp := notyp; rf := 0; sz := 0;
  206.     test(typebegsys,fsys, 10);
  207.     if sy in typebegsys
  208.     then begin
  209.       if sy = ident
  210.       then begin
  211.         x := loc(id);
  212.         if x <> 0
  213.         then with tab[x] do
  214.                if obj <> type1
  215.                then error(29)
  216.                else begin
  217.                  tp := typ; rf := ref; sz := adr;
  218.                  if tp = notyp then error(30)
  219.                end ;
  220.         insymbol;
  221.         if (tp=strngs) and (sy=lbrack)
  222.         then begin
  223.           insymbol;
  224.           constant([rbrack]+fsys,dummy);
  225.           if sy=rbrack then insymbol else error(12);
  226.         end;
  227.       end else if sy = arraysy
  228.                then begin
  229.                  insymbol;
  230.                  if sy = lbrack
  231.                  then insymbol
  232.                  else begin
  233.                    error(11);
  234.                    if sy = lparent
  235.                    then insymbol
  236.                  end ;
  237.                  tp := arrays; arraytyp(rf,sz)
  238.                end else begin  { records }
  239.                  insymbol;
  240.                  enterblock;
  241.                  tp := records; rf := b;
  242.                  if level = lmax then fatal(5);
  243.                  level := level+1; display[level] := b; offset := 0;
  244.                  while not (sy in fsys-[semicolon,comma,ident]+[endsy]) do
  245.                  begin  { field section }
  246.                    if sy = ident
  247.                    then begin
  248.                      t0 := t; entervariable;
  249.                      while sy = comma do
  250.                      begin
  251.                        insymbol; entervariable;
  252.                      end ;
  253.                      if sy = colon then insymbol else error(5);
  254.                      t1 := t;
  255.                      typ(fsys+[semicolon,endsy,comma,ident],eltp,elrf,elsz);
  256.                      while t0 < t1 do
  257.                      begin
  258.                        t0 := t0+1;
  259.                        with tab[t0] do
  260.                        begin
  261.                          typ := eltp;
  262.                          ref := elrf;   normal := true;
  263.                          adr := offset; offset := offset + elsz
  264.                        end
  265.                      end
  266.                    end ; {sy = ident}
  267.                    if sy <> endsy
  268.                    then begin
  269.                      if sy = semicolon
  270.                      then insymbol
  271.                      else begin
  272.                        error(14);
  273.                        if sy = comma then insymbol
  274.                      end ;
  275.                      test([ident,endsy,semicolon], fsys, 6)
  276.                    end
  277.                  end ; {field section}
  278.  
  279.                  btab[rf].vsize := offset; sz := offset;
  280.                  if sz > stacksize then error(61);
  281.                  btab[rf].psize := 0;
  282.                  insymbol; level := level-1
  283.                end ; {records}
  284.       test(fsys, [], 6)
  285.     end
  286.   end  { typ } ;
  287.  
  288.   procedure parameterlist;      { formal parameter list }
  289.  
  290.   var    tp    : types;
  291.          valpar: boolean;
  292.          rf,sz, x, t0: integer;
  293.   begin
  294.     insymbol;
  295.     tp := notyp; rf := 0; sz := 0;
  296.     test([ident, varsy], fsys+[rparent], 7);
  297.     while sy in [ident, varsy] do
  298.     begin
  299.       if sy <> varsy
  300.       then valpar := true
  301.       else begin
  302.         insymbol;
  303.         valpar := false
  304.       end ;
  305.       t0 := t; entervariable;
  306.       while sy = comma do
  307.       begin
  308.         insymbol; entervariable;
  309.       end;
  310.       if sy = colon
  311.       then begin
  312.         insymbol;
  313.         if sy <> ident
  314.         then error(2)
  315.         else begin
  316.           x := loc(id); insymbol;
  317.           if x <> 0
  318.           then with tab[x] do
  319.                if obj <> type1
  320.                then error(29)
  321.                else begin
  322.                  tp := typ;   rf := ref;
  323.                  if valpar then sz := adr else sz := 1
  324.                end ;
  325.           end ;
  326.         test([semicolon,rparent], [comma,ident]+fsys, 14)
  327.       end else error(5);
  328.       while t0 < t do
  329.       begin
  330.         t0 := t0+1;
  331.         with tab[t0] do
  332.         begin
  333.           typ := tp; ref := rf;
  334.           adr := dx; lev := level;
  335.           normal := valpar;
  336.           dx := dx + sz
  337.         end
  338.       end ;
  339.       if sy <> rparent
  340.       then begin
  341.         if sy = semicolon
  342.         then insymbol
  343.         else begin
  344.           error(14);
  345.           if sy = comma then insymbol
  346.         end ;
  347.         test([ident,varsy], [rparent]+fsys, 6)
  348.       end
  349.     end  { while } ;
  350.  
  351.     if sy = rparent
  352.     then begin
  353.       insymbol;
  354.       test([semicolon,colon], fsys, 6)
  355.     end else error(4)
  356.   end  { parameterlist } ;
  357.  
  358.   procedure     constdec;
  359.  
  360.   var    c: conrec;
  361.   begin
  362.     insymbol;
  363.     test([ident], blockbegsys, 2);
  364.     while sy = ident do
  365.     begin
  366.       enter(id,konstant); insymbol;
  367.       if sy = eql
  368.       then insymbol
  369.       else begin
  370.         error(16);
  371.         if sy = becomes then insymbol
  372.       end ;
  373.       constant([semicolon,comma,ident]+fsys,c);
  374.       tab[t].typ := c.tp;
  375.       tab[t].ref := 0;
  376.       if c.tp = reals
  377.       then begin
  378.         enterreal(c.r); tab[t].adr := c1
  379.       end else tab[t].adr := c.i;
  380.       testsemicolon
  381.     end
  382.   end  { constdec } ;
  383.  
  384.   procedure typedeclaration;
  385.  
  386.   var    tp: types;
  387.          rf, sz, t1: integer;
  388.   begin
  389.     insymbol;
  390.     test([ident], blockbegsys, 2);
  391.     while sy = ident do
  392.     begin
  393.       enter(id,type1);
  394.       t1 := t; insymbol;
  395.       if sy = eql
  396.       then insymbol
  397.       else begin
  398.         error(16);
  399.         if sy = becomes then insymbol
  400.       end ;
  401.       typ([semicolon,comma,ident]+fsys, tp, rf, sz);
  402.       with tab[t1] do
  403.       begin
  404.         typ := tp; ref := rf; adr := sz
  405.       end;
  406.       testsemicolon
  407.     end
  408.   end  { typedeclaration } ;
  409.  
  410.   procedure variabledeclaration;
  411.  
  412.   var    tp: types;
  413.          t0, t1, rf, sz: integer;
  414.   begin
  415.     insymbol;
  416.     while sy = ident do
  417.     begin
  418.       t0 := t; entervariable;
  419.       while sy = comma do
  420.       begin
  421.         insymbol; entervariable;
  422.       end ;
  423.       if sy = colon then insymbol else error(5);
  424.       t1 := t;
  425.       typ([semicolon,comma,ident]+fsys, tp, rf, sz);
  426.       while t0 < t1 do
  427.       begin
  428.         t0 := t0+1;
  429.         with tab[t0] do
  430.         begin
  431.           typ := tp;    ref := rf;
  432.           lev := level; adr := dx;
  433.           normal := true;
  434.           dx := dx + sz
  435.         end
  436.       end ;
  437.       testsemicolon
  438.     end
  439.   end  { variabledeclaration } ;
  440.  
  441.   procedure procdeclaration;
  442.  
  443.   var    isfun: boolean;
  444.   begin
  445.     isfun := sy = funcsy;
  446.     insymbol;
  447.     if sy <> ident
  448.     then begin
  449.       error(2); id := '          '
  450.     end;
  451.     if isfun then enter(id,funktion) else enter(id,prozedure);
  452.     tab[t].normal := true;
  453.     insymbol;
  454.     block([semicolon]+fsys, isfun, level+1);
  455.     if sy = semicolon then insymbol else error(14);
  456.     emit(132+ord(isfun))     { exit }
  457.   end  { procdeclaration } ;
  458.  
  459.   procedure statement(fsys: symset);
  460.  
  461.   var    i: integer;
  462.          x: item;
  463.  
  464.     procedure expression(fsys: symset; var x: item); forward;
  465.  
  466.     procedure selector(fsys: symset; var v: item);
  467.  
  468.     var    x: item;
  469.            a,j: integer;
  470.     begin  { sy in [lparent, lbrack, period] }
  471.       repeat
  472.         if sy = period
  473.         then begin
  474.           insymbol;   { field selector }
  475.           if sy <> ident
  476.           then error(2)
  477.           else begin
  478.             if v.typ <> records
  479.             then error(31)
  480.             else begin  {search field identifier }
  481.               j := btab[v.ref].last;
  482.               tab[0].name := id;
  483.               while tab[j].name <> id do j := tab[j].link;
  484.               if j = 0 then error(0);
  485.               v.typ := tab[j].typ;
  486.               v.ref := tab[j].ref;
  487.               a := tab[j].adr;
  488.               if a <> 0 then emit1(9,a)
  489.             end ;
  490.             insymbol
  491.           end
  492.         end else begin  { array selector }
  493.           if sy <> lbrack then error(11);
  494.           if v.typ=strngs then begin
  495.             insymbol;
  496.             expression(fsys+[rbrack],x);
  497.             if x.typ<>ints then error(34) else emit(165);
  498.             v.typ := chars
  499.           end else
  500.           repeat
  501.             insymbol;
  502.             expression(fsys+[comma,rbrack], x);
  503.             if v.typ <> arrays
  504.             then error(28)
  505.             else begin
  506.               a := v.ref;
  507.               if atab[a].inxtyp <> x.typ
  508.               then error(26)
  509.               else if atab[a].elsize = 1
  510.                    then emit1(20,a)
  511.                    else emit1(21,a);
  512.               v.typ := atab[a].eltyp;
  513.               v.ref := atab[a].elref
  514.             end
  515.           until sy <> comma;
  516.  
  517.           if sy = rbrack
  518.           then insymbol
  519.           else begin
  520.             error(12);
  521.             if sy = rparent then insymbol
  522.           end
  523.         end
  524.       until not (sy in [lbrack,lparent,period]);
  525.  
  526.       test (fsys, [], 6)
  527.     end  { selector } ;
  528.  
  529.     procedure call(fsys: symset; i: integer);
  530.  
  531.     var    x: item;
  532.            lastp, cp, k: integer;
  533.  
  534.     begin
  535.       emit1(18,i);   { mark stack }
  536.       lastp := btab[tab[i].ref].lastpar;
  537.       cp := i;
  538.       if sy = lparent
  539.       then begin  { actual parameter list }
  540.         repeat
  541.           insymbol;
  542.           if cp >= lastp
  543.           then error(39)
  544.           else begin
  545.             cp := cp+1;
  546.             if tab[cp].normal
  547.             then begin  {value parameter }
  548.               expression(fsys+[comma,colon,rparent], x);
  549.               if x.typ=tab[cp].typ
  550.               then begin
  551.                 if x.ref <> tab[cp].ref
  552.                 then error(36)
  553.                 else if x.typ = arrays
  554.                      then emit1(22,atab[x.ref].size)
  555.                 else if x.typ = records
  556.                      then emit1(22,btab[x.ref].vsize)
  557.                 else if x.typ = strngs
  558.                      then if x.temp then emit(173)
  559.                                     else emit(172)
  560.               end else if (x.typ=ints) and (tab[cp].typ=reals)
  561.                        then emit1(26,0)
  562.                        else if x.typ<>notyp then error(36);
  563.             end else begin  { var parameter }
  564.               if sy <> ident
  565.               then error(2)
  566.               else begin
  567.                 k := loc(id);
  568.                 insymbol;
  569.                 if k <> 0
  570.                 then begin
  571.                   if tab[k].obj <> vvariable then error(37);
  572.                   x.typ := tab[k].typ;
  573.                   x.ref := tab[k].ref;
  574.                   if tab[k].normal
  575.                   then emit2(0,tab[k].lev,tab[k].adr)
  576.                   else emit2(1,tab[k].lev,tab[k].adr);
  577.                   if sy in [lbrack,lparent,period]
  578.                   then begin
  579.                     if x.typ=strngs then error(60);
  580.                     selector(fsys+[comma,colon,rparent], x);
  581.                   end;
  582.                   if (x.typ<>tab[cp].typ) or (x.ref<>tab[cp].ref)
  583.                   then error(36)
  584.                 end
  585.               end
  586.             end {var parameter}
  587.           end ;
  588.           test([comma,rparent], fsys, 6)
  589.         until sy <> comma;
  590.  
  591.         if sy = rparent then insymbol else error(4)
  592.       end ;
  593.  
  594.       if cp < lastp then error(39);  { too few actual parameters }
  595.       emit1(19, btab[tab[i].ref].psize-1);
  596.       if tab[i].lev < level then emit2(3, tab[i].lev, level)
  597.     end  { call } ;
  598.  
  599.     function resulttype(a,b: types): types;
  600.  
  601.     begin
  602.       if (a>reals) or (b>reals)
  603.       then begin
  604.         error(33);
  605.         resulttype := notyp
  606.       end else if (a=notyp) or (b=notyp)
  607.                then resulttype := notyp
  608.                else if a=ints
  609.                     then if b=ints
  610.                          then resulttype := ints
  611.                          else begin
  612.                            resulttype := reals; emit1(26,1)
  613.                          end
  614.                     else begin
  615.                       resulttype := reals;
  616.                       if b=ints then emit1(26,0)
  617.                     end
  618.     end   { resulttype } ;
  619.  
  620.     procedure expression {fsys:symset; var x:item};
  621.  
  622.     var    y :item;
  623.            op:symbol;
  624.            t :integer;
  625.  
  626.       procedure simpleexpression(fsys:symset; var x:item);
  627.  
  628.       var    y :item;
  629.              op:symbol;
  630.              t :integer;
  631.  
  632.         procedure term(fsys:symset; var x:item);
  633.  
  634.         var    y :item;
  635.                op:symbol;
  636.                ts:typset;
  637.  
  638.           procedure factor(fsys:symset; var x:item);
  639.  
  640.           var    i,f: integer;
  641.  
  642.             procedure standfct(n: integer);
  643.  
  644.             var    ts: typset;
  645.  
  646.             begin { standard function no. n }
  647.             if n=19
  648.             then emit1(8,n)
  649.             else begin
  650.               if sy = lparent
  651.               then insymbol
  652.               else error(9);
  653.               if (n < 17) or (n > 19)
  654.               then begin
  655.                 expression(fsys+[comma,rparent],x);
  656.  
  657.                 case n of
  658.  
  659.  { abs,sqr }    0,2: begin
  660.                        ts := [ints,reals];
  661.                        tab[i].typ := x.typ;
  662.                        if x.typ = reals then n := n+1
  663.                      end;
  664.  
  665.  { odd,chr }    4,5: ts := [ints];
  666.  
  667.  { ord }          6: ts := [ints,bools,chars];
  668.  
  669.  { succ,pred }  7,8: begin
  670.                        ts := [ints,bools,chars];
  671.                        tab[i].typ := x.typ
  672.                      end;
  673.  
  674.  { round,trunc } 9,10,11,12,13,14,15,16:
  675.  { sin,cos,... }     begin
  676.                        ts := [ints,reals];
  677.                        if x.typ = ints then emit1(26,0)
  678.                      end;
  679.  
  680.  { length }      20: begin
  681.                        ts := [strngs,chars];
  682.                        if x.temp then n := n+1;
  683.                        if x.typ = chars then n := n+2
  684.                      end;
  685.  
  686.  { copy }        23: begin
  687.                        ts := [strngs,chars];
  688.                        if x.typ = chars then n := n+2
  689.                          else if x.temp then n := n+1;
  690.                        test([comma], [comma,rparent]+fsys, 59);
  691.                        if sy = comma then begin
  692.                          insymbol;
  693.                          expression(fsys+[comma,rparent],y);
  694.                          if y.typ <> ints
  695.                            then if y.typ <> notyp then error(34);
  696.                          test([comma,rparent], fsys, 6);
  697.                          if sy = comma then begin
  698.                            insymbol;
  699.                            expression(fsys+[rparent],y);
  700.                            if y.typ <> ints
  701.                              then if y.typ <> notyp then error(34);
  702.                          end else emit1(24,nmax);
  703.                        end;
  704.                      end;
  705.  
  706. { pos }          26: begin
  707.                        ts := [strngs,chars];
  708.                        if x.typ = chars then n := n+2
  709.                          else if x.temp then n := n+1;
  710.                        test([comma], [comma]+fsys, 59);
  711.                        if sy = comma then begin
  712.                          insymbol;
  713.                          expression(fsys+[rparent],y);
  714.                          if y.typ <> strngs
  715.                          then if y.typ <> notyp then error(38) else
  716.                          else if y.temp then n := n+4;
  717.                        end
  718.                      end;
  719.  
  720. { str }          33: begin
  721.                        ts := [ints,reals];
  722.                        if x.typ = reals then n := n+1
  723.                      end;
  724.  
  725. { val,rval }  35,37: begin
  726.                        ts := [strngs];
  727.                        if x.temp then n := n+1
  728.                      end;
  729.  
  730.                 end ; { case }
  731.  
  732.                 if x.typ in ts
  733.                 then emit1(8,n)
  734.                 else if x.typ <> notyp
  735.                      then error(48);
  736.               end else begin    { n in [17,18] }
  737.                 if sy <> ident
  738.                 then error(2)
  739.                 else if id <> 'input     '
  740.                      then error(0)
  741.                      else insymbol;
  742.                 emit1(8,n);
  743.               end ;
  744.               x.typ := tab[i].typ; x.temp := true;
  745.               if sy = rparent then insymbol else error(4)
  746.             end end { standfct } ;
  747.  
  748.           begin  { factor }
  749.             x.typ := notyp;
  750.             x.ref := 0;
  751.             test(facbegsys, fsys, 58);
  752.             while sy in facbegsys do begin
  753.             case sy of
  754.        ident: begin
  755.                 i := loc(id);
  756.                 insymbol;
  757.                 with tab[i] do
  758.  
  759.                   case obj of
  760.  
  761.           konstant: begin
  762.                       x.typ := typ;
  763.                       x.ref := 0; x.temp := false;
  764.                       if x.typ = reals
  765.                       then emit1(25,adr)
  766.                       else emit1(24,adr)
  767.                     end ;
  768.  
  769.          vvariable: begin
  770.                       x.typ := typ;
  771.                       x.ref := ref; x.temp := false;
  772.                       if sy in [lbrack,lparent,period]
  773.                       then begin
  774.                         if normal then f := 0 else f := 1;
  775.                         if x.typ=strngs then begin
  776.                           emit2(f+1,lev,adr);
  777.                           selector(fsys,x);  end
  778.                         else begin
  779.                           emit2(f,lev,adr);
  780.                           selector(fsys,x);
  781.                           if x.typ in stantyps then emit(134);
  782.                         end
  783.                       end else begin
  784.                         if x.typ in stantyps
  785.                         then if normal
  786.                              then f := 1
  787.                              else f := 2
  788.                         else if normal then f := 0 else f :=1;
  789.                         emit2(f, lev, adr)
  790.                       end
  791.                     end ;
  792.  
  793.   type1, prozedure: error(44);
  794.  
  795.          funktion : begin
  796.                       x.typ := typ; x.temp := true;
  797.                       if lev <> 0
  798.                       then call(fsys, i)
  799.                       else standfct(adr)
  800.                     end
  801.  
  802.                   end  { case obj, with }
  803.                 end;   { ident }
  804.  
  805.      realcon: begin
  806.                 x.typ := reals; x.ref := 0;
  807.                 enterreal(rnum);
  808.                 emit1(25, c1);
  809.                 insymbol
  810.               end;
  811.      charcon: begin
  812.                 x.typ := chars; x.ref := 0; x.temp := false;
  813.                 emit1(24, inum);
  814.                 insymbol
  815.               end;
  816.       intcon: begin
  817.                 x.typ := ints; x.ref := 0;
  818.                 emit1(24, inum);
  819.                 insymbol
  820.               end;
  821.    stringcon: begin
  822.                 x.typ := strngs; x.ref := 0; x.temp := false;
  823.                 emit1(24,seg(spnt^));
  824.                 insymbol
  825.               end;
  826.      lparent: begin
  827.                 insymbol;
  828.                 expression(fsys+[rparent], x);
  829.                 if sy = rparent
  830.                 then insymbol
  831.                 else error(4)
  832.               end;
  833.        notsy: begin
  834.                 insymbol;
  835.                 factor(fsys,x);
  836.                 if x.typ=bools
  837.                 then emit(135)
  838.                 else if x.typ<>notyp
  839.                      then error(32)
  840.               end;
  841.             end;  { case sy }
  842.             test(fsys, facbegsys, 6);
  843.             end { while }
  844.           end { factor } ;
  845.  
  846.         begin { term }
  847.           factor(fsys+[times,rdiv,idiv,imod,andsy], x);
  848.           while sy in [times,rdiv,idiv,imod,andsy] do
  849.           begin
  850.             op := sy;
  851.             insymbol;
  852.             factor(fsys+[times,rdiv,idiv,imod,andsy], y);
  853.             if op = times
  854.             then begin
  855.               x.typ := resulttype(x.typ, y.typ);
  856.  
  857.               case x.typ of
  858.          notyp: ;
  859.          ints : emit(157);
  860.          reals: emit(160);
  861.               end
  862.  
  863.             end else if op = rdiv
  864.                      then begin
  865.                        if x.typ = ints
  866.                        then begin
  867.                          emit1(26,1);
  868.                          x.typ := reals
  869.                        end ;
  870.                        if y.typ = ints
  871.                        then begin
  872.                          emit1(26,0);
  873.                          y.typ := reals
  874.                        end ;
  875.                        if (x.typ=reals) and (y.typ=reals)
  876.                        then emit(161)
  877.                        else begin
  878.                          if (x.typ<>notyp) and (y.typ<>notyp)
  879.                          then error(33);
  880.                          x.typ := notyp
  881.                        end
  882.                      end else
  883.                        if op = andsy
  884.                        then begin
  885.                          if (x.typ=bools) and (y.typ=bools)
  886.                          then emit(156)
  887.                          else begin
  888.                            if (x.typ<>notyp) and (y.typ<>notyp)
  889.                            then error(32);
  890.                            x.typ := notyp
  891.                          end
  892.                        end else begin     { op in [idiv,imod] }
  893.                          if (x.typ=ints) and (y.typ=ints)
  894.                          then if op=idiv
  895.                               then emit(158)
  896.                               else emit(159)
  897.                          else begin
  898.                            if (x.typ<>notyp) and (y.typ<>notyp)
  899.                            then error(34);
  900.                            x.typ := notyp
  901.                          end
  902.                        end
  903.           end {while}
  904.         end { term } ;
  905.  
  906.       begin { simpleexpression }
  907.         if sy in [plus,minus]
  908.         then begin
  909.           op := sy;
  910.           insymbol;
  911.           term(fsys+[plus,minus], x);
  912.           if x.typ > reals
  913.           then error(33)
  914.           else if op = minus
  915.                then if x.typ = reals
  916.                     then emit(164)
  917.                     else emit(136)
  918.         end else term(fsys+[plus,minus,orsy], x);
  919.         while sy in [plus,minus,orsy] do
  920.         begin
  921.           op := sy;
  922.           insymbol;
  923.           term(fsys+[plus,minus,orsy], y);
  924.           if op = orsy
  925.           then begin
  926.             if (x.typ=bools) and (y.typ=bools)
  927.             then emit(151)
  928.             else begin
  929.               if (x.typ <> notyp) and (y.typ<>notyp)
  930.               then error(32);
  931.               x.typ := notyp
  932.             end
  933.           end else if (x.typ = chars) or (x.typ = strngs)
  934.           then begin
  935.             if not((y.typ = chars) or (y.typ = strngs))
  936.             then begin error(38);
  937.                    x.typ := notyp; end
  938.             else begin
  939.                    if x.typ = chars then t := 0 else t := 1;
  940.                    if y.typ = strngs then t := t+2;
  941.                    if x.temp then t := t+4;
  942.                    if y.temp then t := t+8;
  943.                    emit1(7,t);
  944.                    x.typ := strngs; x.temp := true;
  945.                  end
  946.             end
  947.           else begin
  948.             x.typ := resulttype(x.typ, y.typ);
  949.  
  950.             case x.typ of
  951.        notyp: ;
  952.        ints : if op = plus
  953.               then emit(152)
  954.               else emit(153);
  955.        reals: if op = plus
  956.               then emit(154)
  957.               else emit(155)
  958.             end {case}
  959.  
  960.           end
  961.         end {while}
  962.       end { simpleexpression } ;
  963.  
  964.     begin { expression }
  965.       simpleexpression(fsys+[eql,neq,lss,leq,gtr,geq], x);
  966.       if sy in [eql,neq,lss,leq,gtr,geq]
  967.       then begin
  968.         op := sy;
  969.         insymbol;
  970.         simpleexpression(fsys, y);
  971.         if (x.typ in [notyp,ints,bools,chars]) and (x.typ = y.typ)
  972.         then case op of
  973.  
  974.              eql: emit(145);
  975.              neq: emit(146);
  976.              lss: emit(147);
  977.              leq: emit(148);
  978.              gtr: emit(149);
  979.              geq: emit(150);
  980.  
  981.              end
  982.         else begin
  983.           if x.typ = ints
  984.           then begin
  985.             x.typ := reals;
  986.             emit1(26,1)
  987.           end else if y.typ = ints
  988.                    then begin
  989.                      y.typ := reals;
  990.                      emit1(26,0)
  991.                    end ;
  992.           if (x.typ=reals) and (y.typ=reals)
  993.           then case op of
  994.  
  995.                eql: emit(139);
  996.                neq: emit(140);
  997.                lss: emit(141);
  998.                leq: emit(142);
  999.                gtr: emit(143);
  1000.                geq: emit(144);
  1001.  
  1002.                end
  1003.           else if (x.typ in [chars,strngs]) and (y.typ in [chars,strngs])
  1004.                then begin
  1005.                  if x.typ=strngs then t := 1 else t := 0;
  1006.                  if y.typ=strngs then t := t+2;
  1007.                  if x.temp then t := t+4;
  1008.                  if y.temp then t := t+8;
  1009.                  if op in [eql,leq,geq] then t := t+16;
  1010.                  if op in [neq,gtr,geq] then t := t+32;
  1011.                  if op in [neq,lss,leq] then t := t+64;
  1012.                  emit1(32,t);
  1013.                end
  1014.                else error(35)
  1015.              end ;
  1016.              x.typ := bools
  1017.       end
  1018.  end { expression } ;
  1019.  
  1020.     procedure assignment(lv,ad: integer);
  1021.  
  1022.     var    x,y: item;
  1023.            f  : integer;
  1024.     begin              { tab[i].obj in [vvariable,funktion] }
  1025.       x.typ := tab[i].typ;
  1026.       x.ref := tab[i].ref;
  1027.       if tab[i].normal then f := 0 else f := 1;
  1028.       emit2(f, lv, ad);
  1029.       if sy in [lbrack,lparent,period]
  1030.       then if x.typ<>strngs
  1031.            then selector([becomes,eql]+fsys, x)
  1032.            else error(60);
  1033.       if sy = becomes
  1034.       then insymbol
  1035.       else begin
  1036.         error(51);
  1037.         if sy = eql then insymbol
  1038.       end ;
  1039.  
  1040.       expression(fsys, y);
  1041.       if x.typ = y.typ
  1042.       then if x.typ in stantyps
  1043.            then if x.typ=strngs
  1044.                 then if y.temp then emit(166)
  1045.                                else emit(169)
  1046.                 else emit(138)
  1047.            else if x.ref <> y.ref
  1048.                 then error(46)
  1049.                 else if x.typ = arrays
  1050.                      then emit1(23,atab[x.ref].size)
  1051.                      else emit1(23,btab[x.ref].vsize)
  1052.       else if (x.typ=reals) and (y.typ=ints)
  1053.       then begin
  1054.         emit1(26,0);
  1055.         emit(138) end
  1056.       else if (x.typ=chars) and (y.typ=strngs)
  1057.            then begin
  1058.                   if y.temp then t := 8 else t := 0;
  1059.                   emit1(31,t); end
  1060.       else if (x.typ=strngs) and (y.typ=chars)
  1061.            then emit(168)
  1062.       else if (x.typ=strngs) and (y.typ=arrays)
  1063.            then if atab[y.ref].eltyp = chars
  1064.                 then begin emit1(167,atab[y.ref].size); emit(166) end
  1065.                 else
  1066.       else if (x.typ=arrays) and (y.typ=strngs)
  1067.            then if atab[x.ref].eltyp = chars
  1068.                 then if y.temp then emit1(175,atab[x.ref].size)
  1069.                                else emit1(174,atab[x.ref].size)
  1070.                 else
  1071.       else if (x.typ<>notyp) and (y.typ<>notyp)
  1072.            then error(46)
  1073.     end { assignment } ;
  1074.  
  1075.     procedure compoundstatement;
  1076.  
  1077.     begin
  1078.       insymbol;
  1079.       statement([semicolon,endsy]+fsys);
  1080.       while sy in [semicolon]+statbegsys do
  1081.       begin
  1082.         if sy = semicolon
  1083.         then insymbol
  1084.         else error(14);
  1085.         statement([semicolon,endsy]+fsys)
  1086.       end ;
  1087.       if sy = endsy then insymbol else error(57)
  1088.     end { compoundstatement } ;
  1089.  
  1090.     procedure ifstatement;
  1091.  
  1092.     var    x: item;
  1093.            lc1,lc2: integer;
  1094.     begin
  1095.       insymbol;
  1096.       expression(fsys+[thensy,dosy], x);
  1097.       if not (x.typ in [bools,notyp])
  1098.       then error(17);
  1099.       lc1 := lc;
  1100.       emit(11);     { jmpc }
  1101.  
  1102.       if sy = thensy
  1103.       then insymbol
  1104.       else begin
  1105.         error(52);
  1106.         if sy = dosy
  1107.         then insymbol
  1108.       end ;
  1109.  
  1110.       statement(fsys+[elsesy]);
  1111.  
  1112.       if sy = elsesy
  1113.       then begin
  1114.         insymbol;                lc2 := lc;
  1115.         emit(10);        code[lc1].y := lc;
  1116.         statement(fsys); code[lc2].y := lc
  1117.       end
  1118.       else code[lc1].y := lc
  1119.     end { ifstatement } ;
  1120.  
  1121.     procedure casestatement;
  1122.  
  1123.     var    x: item;
  1124.     i,j,k,lc1: integer;
  1125.     casetab: array [1..csmax] of
  1126.               packed record
  1127.                 val, lc: index
  1128.               end ;
  1129.     exittab: array [1..csmax] of integer;
  1130.  
  1131.       procedure caselabel;
  1132.  
  1133.       var    lab: conrec;
  1134.              k  : integer;
  1135.       begin
  1136.         constant(fsys+[comma,colon], lab);
  1137.         if lab.tp <> x.typ
  1138.         then error(47)
  1139.         else if i = csmax
  1140.              then fatal(6)
  1141.              else begin
  1142.                i := i+1;    k := 0;
  1143.                casetab[i].val :=lab.i;
  1144.                casetab[i].lc  := lc;
  1145.                repeat
  1146.                  k := k+1
  1147.                until casetab[k].val = lab.i;
  1148.  
  1149.                if k < i then error(1);   { multiple definition }
  1150.              end
  1151.       end { caselabel } ;
  1152.  
  1153.       procedure onecase;
  1154.  
  1155.       begin
  1156.         if sy in constbegsys
  1157.         then begin
  1158.           caselabel;
  1159.           while sy = comma do
  1160.           begin
  1161.             insymbol; caselabel
  1162.           end ;
  1163.           if sy = colon
  1164.           then insymbol else error(5);
  1165.           statement([semicolon,endsy]+fsys);
  1166.           j := j+1;
  1167.           exittab[j] := lc; emit(10)
  1168.         end
  1169.       end { onecase } ;
  1170.  
  1171.     begin {casestatement}
  1172.       insymbol;
  1173.       i := 0;   j := 0;
  1174.       expression(fsys+[ofsy,comma,colon], x);
  1175.       if not (x.typ in [ints,bools,chars,notyp])
  1176.       then error(23);
  1177.       lc1 := lc; emit(12);  { jmpx }
  1178.  
  1179.       if sy = ofsy then insymbol else error(8);
  1180.       onecase;
  1181.       while sy = semicolon do
  1182.       begin
  1183.         insymbol;
  1184.         onecase
  1185.       end ;
  1186.       code[lc1].y := lc;
  1187.       for k := 1 to i do
  1188.       begin
  1189.         emit1(13,casetab[k].val);
  1190.         emit1(13,casetab[k].lc)
  1191.       end ;
  1192.       emit1(10,0);
  1193.       for k := 1 to j do code[exittab[k]].y := lc;
  1194.       if sy = endsy then insymbol else error(57)
  1195.     end { casestatement } ;
  1196.  
  1197.     procedure repeatstatement;
  1198.  
  1199.     var    x  : item;
  1200.            lc1: integer;
  1201.     begin
  1202.       lc1 := lc;
  1203.       insymbol;
  1204.       statement([semicolon,untilsy]+fsys);
  1205.       while sy in [semicolon]+statbegsys do
  1206.       begin
  1207.         if sy = semicolon then insymbol else error(14);
  1208.         statement([semicolon,untilsy]+fsys)
  1209.       end ;
  1210.       if sy = untilsy
  1211.       then begin
  1212.         insymbol;
  1213.         expression(fsys, x);
  1214.         if not (x.typ in [bools,notyp]) then error(17);
  1215.         emit1(11, lc1)
  1216.       end else error(53)
  1217.     end { repeatstatement } ;
  1218.  
  1219.     procedure whilestatement;
  1220.  
  1221.     var    x: item;
  1222.            lc1,lc2: integer;
  1223.     begin
  1224.       insymbol;
  1225.       lc1 := lc;
  1226.       expression(fsys+[dosy], x);
  1227.       if not (x.typ in [bools,notyp]) then error(17);
  1228.       lc2 := lc; emit(11);
  1229.  
  1230.       if sy = dosy then insymbol else error(54);
  1231.       statement(fsys);
  1232.       emit1(10,lc1);
  1233.       code[lc2].y := lc
  1234.     end { whilestatement } ;
  1235.  
  1236.     procedure forstatement;
  1237.  
  1238.     var    cvt: types;
  1239.            x  : item;
  1240.            i,f,lc1,lc2: integer;
  1241.     begin
  1242.       insymbol;
  1243.       if sy = ident
  1244.       then begin
  1245.         i := loc(id);
  1246.         insymbol;
  1247.         if i = 0
  1248.         then cvt := ints
  1249.         else if tab[i].obj = vvariable
  1250.              then begin
  1251.                cvt := tab[i].typ;
  1252.                if tab[i].normal then f := 0 else f := 1;
  1253.                emit2(f, tab[i].lev, tab[i].adr);
  1254.                if not (cvt in [notyp,ints,bools,chars]) then error(18)
  1255.              end else begin
  1256.                error(37); cvt := ints
  1257.              end
  1258.       end else skip([becomes,tosy,downtosy,dosy]+fsys, 2);
  1259.  
  1260.       if sy = becomes
  1261.       then begin
  1262.         insymbol;
  1263.         expression([tosy,downtosy,dosy]+fsys, x);
  1264.         if x.typ <> cvt then error(19);
  1265.       end else skip([tosy,downtosy,dosy]+fsys, 51);
  1266.       f := 14;
  1267.  
  1268.       if sy in [tosy, downtosy]
  1269.       then begin
  1270.         if sy = downtosy then f := 16;
  1271.         insymbol;
  1272.         expression([dosy]+fsys, x);
  1273.         if x.typ <> cvt then error(19)
  1274.       end else skip([dosy]+fsys, 55);
  1275.  
  1276.       lc1 := lc; emit(f);
  1277.       if sy = dosy then insymbol else error(54);
  1278.       lc2 := lc;
  1279.       statement(fsys);
  1280.       emit1(f+1,lc2);
  1281.       code[lc1].y := lc
  1282.     end { forstatement } ;
  1283.  
  1284.     procedure standproc(n: integer);
  1285.  
  1286.     var    i,f: integer;
  1287.            x,y: item;
  1288.     begin
  1289.  
  1290.       case n of
  1291.  
  1292.  1,2: begin { read }
  1293.         if sy = lparent
  1294.         then begin
  1295.           repeat
  1296.             insymbol;
  1297.             if sy <> ident
  1298.             then error(2)
  1299.             else begin
  1300.               i := loc(id);
  1301.               insymbol;
  1302.               if i <> 0
  1303.               then if tab[i].obj <> vvariable
  1304.                    then error( 37)
  1305.                    else begin
  1306.                      x.typ := tab[i].typ;
  1307.                      x.ref := tab[i].ref;
  1308.                      if tab[i].normal then f := 0 else f := 1;
  1309.                      emit2(f, tab[i].lev, tab[i].adr);
  1310.                      if sy in [lbrack,lparent,period]
  1311.                      then begin
  1312.                             if x.typ=strngs then error(60);
  1313.                             selector(fsys+[comma,rparent], x); end;
  1314.                      if x.typ in [ints,reals,chars,strngs,notyp]
  1315.                      then emit1(27,ord(x.typ))
  1316.                      else error(41)
  1317.                    end
  1318.             end ;
  1319.             test([comma,rparent], fsys, 6);
  1320.           until sy <> comma;
  1321.  
  1322.           if sy = rparent then insymbol else error(4)
  1323.         end ;
  1324.         if n = 2 then emit(162)
  1325.       end ;
  1326.  3,4: begin { write }
  1327.         if sy = lparent
  1328.         then begin
  1329.  
  1330.           repeat
  1331.             insymbol;
  1332.             expression(fsys+[comma,colon,rparent], x);
  1333.             if not (x.typ in stantyps) then error(41);
  1334.             if sy = colon
  1335.             then begin
  1336.               insymbol;
  1337.               expression(fsys+[comma,colon,rparent], y);
  1338.               if y.typ <> ints then error(43);
  1339.               if sy = colon
  1340.               then begin
  1341.                 if x.typ <> reals then error( 42);
  1342.                 insymbol;
  1343.                 expression(fsys+[comma,rparent], y);
  1344.                 if y.typ <> ints then error(43);
  1345.                 emit(137)
  1346.               end else begin
  1347.                 if x.typ=strngs
  1348.                 then if x.temp then emit(177) else emit(176)
  1349.                 else emit1(30, ord(x.typ))
  1350.               end
  1351.             end else if x.typ=strngs
  1352.                      then if x.temp then emit(171)
  1353.                                     else emit(170)
  1354.                      else emit1(29, ord(x.typ))
  1355.           until sy <> comma;
  1356.  
  1357.           if sy = rparent then insymbol else error(4)
  1358.         end ;
  1359.         if n = 4 then emit(163)
  1360.       end ; {write}
  1361.  
  1362.       end { case }
  1363.  
  1364.     end { standproc } ;
  1365.  
  1366.   begin { statement }
  1367.     if sy in statbegsys+[ident]
  1368.     then case sy of
  1369.  
  1370.        ident: begin
  1371.                 i := loc(id);
  1372.                 insymbol;
  1373.                 if i <> 0
  1374.                 then case tab[i].obj of
  1375.  
  1376.          konstant, type1: error(45);
  1377.                vvariable: assignment(tab[i].lev, tab[i].adr);
  1378.                prozedure: if tab[i].lev <> 0
  1379.                           then call(fsys, i)
  1380.                           else standproc(tab[i].adr);
  1381.                 funktion: if tab[i].ref = display[level]
  1382.                           then assignment(tab[i].lev+1, 0)
  1383.                           else error(45)
  1384.                      end {case}
  1385.  
  1386.               end ;
  1387.  
  1388.      beginsy: compoundstatement;
  1389.         ifsy: ifstatement;
  1390.       casesy: casestatement;
  1391.      whilesy: whilestatement;
  1392.     repeatsy: repeatstatement;
  1393.        forsy: forstatement;
  1394.  
  1395.          end; {case}
  1396.  
  1397.     test(fsys, [], 14)
  1398.   end { statement } ;
  1399.  
  1400. begin { block }
  1401.   dx := 6; prt := t;
  1402.   if level > lmax then fatal(5);
  1403.   test([lparent,colon,semicolon], fsys, 14);
  1404.  
  1405.   enterblock;
  1406.            prb := b;      display[level] := b;
  1407.   tab[prt].typ := notyp;    tab[prt].ref := prb;
  1408.   if (sy = lparent) and (level > 1) then parameterlist;
  1409.   btab[prb].lastpar := t;btab[prb].psize := dx;
  1410.  
  1411.   if isfun
  1412.   then if sy = colon
  1413.        then begin
  1414.          insymbol;   { function type }
  1415.          if sy = ident
  1416.          then begin
  1417.            x := loc(id);
  1418.            insymbol;
  1419.            if x <> 0
  1420.            then if tab[x].obj <> type1
  1421.                 then error(29)
  1422.                 else if tab[x].typ in stantyps
  1423.                      then tab[prt].typ := tab[x].typ
  1424.                      else error(15)
  1425.          end else skip([semicolon]+fsys, 2)
  1426.        end else error(5);
  1427.   if sy = semicolon then insymbol else error(14);
  1428.  
  1429.   repeat
  1430.     if sy = constsy then constdec;
  1431.     if sy = typesy then typedeclaration;
  1432.     if sy = varsy then variabledeclaration;
  1433.     btab[prb].vsize := dx;
  1434.     while sy in [procsy,funcsy] do procdeclaration;
  1435.     test([beginsy], blockbegsys+statbegsys, 56)
  1436.   until sy in statbegsys;
  1437.  
  1438.   tab[prt].adr := lc;
  1439.   insymbol;
  1440.   statement([semicolon,endsy]+fsys);
  1441.  
  1442.   while sy in [semicolon]+statbegsys do
  1443.   begin
  1444.     if sy = semicolon then insymbol else error(14);
  1445.     statement([semicolon,endsy]+fsys)
  1446.   end ;
  1447.   if sy = endsy then insymbol else error(57);
  1448.   test(fsys+[period], [], 6)
  1449. end { block } ;
  1450.  
  1451.